package com.kehutong.common;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContextEvent;

import org.coraframework.authz.AthInterceptor;
import org.coraframework.boot.Application;
import org.coraframework.config.Config;
import org.coraframework.inject.Binder;
import org.coraframework.mvc.http.component.MadvocConfig;
import org.coraframework.mvc.http.interceptor.ServletConfigInterceptor;
import org.coraframework.mvc.webservice.URLDecorder;
import org.coraframework.mvc.webservice.WebServiceClient;
import org.coraframework.orm.bytecode.CodeFactory;
import org.coraframework.orm.jdbc.JDBCRegister;
import org.coraframework.orm.jdbc.dialect.MySQLRegister;
import org.coraframework.threadpool.ThreadPool;
import org.coraframework.util.Ioc;
import org.coraframework.util.Objects;

import com.kehutong.common.interceptor.LogInterceptor;
import com.kehutong.common.interceptor.PermissionInterceptor;
import com.kehutong.common.interceptor.ValidInterceptor;

public abstract class BaseLauncher {

	public void bind(Binder binder) {
		binder.bind(JDBCRegister.class).to(MySQLRegister.class);
		binder.bind(CodeFactory.class).toInstance(CodeFactory.getInstance());
		binder.bind(AthInterceptor.class).to(PermissionInterceptor.class);
		binder.bind(WebServiceClient.class).toInstance(initWerbService());

		this.initThreadPool(binder);
	}

	@SuppressWarnings("unchecked")
	public void init(ServletContextEvent Event) throws Exception {
		MadvocConfig config = Ioc.getInstance(MadvocConfig.class);
		config.setDefaultInterceptors(ServletConfigInterceptor.class, ValidInterceptor.class, LogInterceptor.class);
	}

	/**
	 * 初始化绑定线程池
	 * @param binder
	 */
	private void initThreadPool(Binder binder) {
		int minThreads = Runtime.getRuntime().availableProcessors();
		final ThreadPool threadPool = new ThreadPool("threadpool", minThreads << 2, 2, minThreads);
		binder.bind(ThreadPool.class).toInstance(threadPool);
	}

	/**
	 * 初始化服务器之间通宵
	 */
	private WebServiceClient initWerbService() {
		Config conf = Application.getConfig("web");
		WebServiceClient webservice = new WebServiceClient(conf.getString("appId"), conf.getString("secret"));
		
		conf = Application.getConfig("services");
		webservice.setUrlDecoder(new KhtHttpUrlDecoder(conf));
		
		return webservice;
	}
	
	private class KhtHttpUrlDecoder implements URLDecorder {
		
		KhtHttpUrlDecoder(Config config) {
			Map<String, String> map = new HashMap<>();
			config.entrySet().forEach(e->map.put(e.getKey(), e.getValue().unwrapped().toString()));
			reqMapping = Collections.unmodifiableMap(map);
		}
		
		private Map<String, String> reqMapping;
		
		@Override
		public String getPrefixUrl(String page) {
			if (Objects.isEmpty(page)) {
				throw new RuntimeException("url can not null");
			}
			
			if (page.charAt(0) == 'h' &&
				page.charAt(1) == 't' &&
				page.charAt(2) == 't' &&
				page.charAt(3) == 'p') {
				return page;
			}
			
			
			if (page.charAt(0) != '/') {
				throw new RuntimeException("url must begin with '/'");
			}
			
			String prefix = getPrefix(page);
			return reqMapping.get(prefix) + page;
		}

		private String getPrefix(String url) {
			List<String> signs = parseArray(url);
			String prefix = signs.get(0);
			if ("kht-bin".equals(prefix)) {
				return signs.get(1);
			}

			return prefix;
		}
		
		private List<String> parseArray(String context) {
			List<String> contentList = new ArrayList<>();
			
			if (Objects.nonEmpty(context)) {
				StringBuilder buf = new StringBuilder();
				char[] chs = context.toCharArray();
				for (char ch : chs) {
					if (ch == '/') {
						if (buf.length() > 0) {
							contentList.add(buf.toString());
						}
						buf = new StringBuilder();
						continue;
					}
					
					buf.append(ch);
				}
				
				if (buf.length() > 0 && buf.length() > 0) {
					contentList.add(buf.toString());
				}
			}
			return contentList;
		}
		
	}
}